package com.example.sqldemo.spring_transaction;


import com.example.sqldemo.Service.UserService;
import com.example.sqldemo.mapper.SqlMapper;
import com.example.sqldemo.pojo.AuditModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionException;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;

import javax.annotation.Resource;

@Component
public class SpringTransactionTest {

    @Resource
    private SqlMapper sqlMapper;

    /**
     * jdbc 的 数据库的一个连接的template ,用于执行各种的sql语句
     */
    @Autowired
    private JdbcTemplate jdbcTemplate;

    /**
     * 事务管理器
     */
    @Autowired
    private PlatformTransactionManager transactionManager;

    /**
     * Spring的一个封装过的事物template: 可以设置事务的隔离级别和事务的传播行为
     */
    @Autowired
    private TransactionTemplate transactionTemplate;

    // 需要自己进行事物的提交和回滚

    @Transactional(rollbackFor = Exception.class)
    public void test1(String[] args) {
        // 1. 定义默认的事物属性
        DefaultTransactionDefinition definition = new DefaultTransactionDefinition();
        // 2. 获取事务
        TransactionStatus status = transactionManager.getTransaction(definition);
        try {
            // 3. 执行sql
            jdbcTemplate.update("update user set money = ? where username = ?", 100, "李四");
            // 提交事务
            transactionManager.commit(status);
        } catch (DataAccessException | TransactionException e) {
            e.printStackTrace();
            // 事务回滚
            transactionManager.rollback(status);
        }
    }

    // 使用 Spring封装的事物的template, 帮助你进行事物的提交和回滚
    public void test2() {
        transactionTemplate.execute(new TransactionCallbackWithoutResult() {
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus status) {
                // 3. 执行sql
                AuditModel auditModel = new AuditModel();
                auditModel.setId(1232313232);
                auditModel.setCountry("西班牙");
                auditModel.setUser("哈哈哈哈");
                sqlMapper.insert(auditModel);
            }
        });
    }

    @Autowired
    private UserService userService;

    @Transactional(readOnly = true, timeout = 60)
    public void m1() {
        AuditModel auditModel = new AuditModel();
        auditModel.setId(1232313233);
        auditModel.setCountry("西班牙");
        auditModel.setUser("哈哈哈哈");
        sqlMapper.insert(auditModel);
        // 事务2
        userService.insertUser();
    }
}
